package ShapeParsingAndAnalysis;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.HashMap;

public class ShapeService {
    private ShapeParser parser = new ShapeParser();
    private ArrayList<Shape> lastParsedShapes; // Store last parsed shapes for visualization

    public ArrayList<Shape> parseFile(String filePath) {
        lastParsedShapes = parser.parseFile(filePath);

        if (lastParsedShapes.isEmpty()) {
            throw new IllegalArgumentException("Invalid file or no shapes found");
        }
        return lastParsedShapes;
    }

    public HashMap<String, Integer> countByType(ArrayList<Shape> shapes) {
        HashMap<String, Integer> counts = new HashMap<>();
        for (Shape shape : shapes) {
            counts.merge(shape.getType(), 1, Integer::sum);
        }
        return counts;
    }

    public double totalArea(ArrayList<Shape> shapes) {
        return shapes.stream().mapToDouble(Shape::getArea).sum();
    }

    public void displayShapes(ArrayList<Shape> shapes, JTextArea outputArea) {
        for (Shape shape : shapes) {
            outputArea.append(shape.getType() + ": Area = " + shape.getArea() + ", Perimeter = " + shape.getPerimeter() + "\n");
        }
    }

    public JPanel createMainPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createTitledBorder("Shape Analysis"));

        // Input panel
        JPanel inputPanel = new JPanel(new FlowLayout());
        JTextField filePathField = new JTextField(20);
        JButton browseButton = new JButton("Browse");
        JButton analyzeButton = new JButton("Analyze Shapes");
        JButton visualizeButton = new JButton("Visualize Shapes");
        inputPanel.add(new JLabel("Shape File:"));
        inputPanel.add(filePathField);
        inputPanel.add(browseButton);
        inputPanel.add(analyzeButton);
        inputPanel.add(visualizeButton);

        // Output and visualization area
        JTextArea outputArea = new JTextArea(10, 40);
        outputArea.setEditable(false);
        JScrollPane textScrollPane = new JScrollPane(outputArea);

        // Visualization canvas
        ShapeCanvas canvas = new ShapeCanvas();
        JScrollPane canvasScrollPane = new JScrollPane(canvas);
        canvasScrollPane.setPreferredSize(new Dimension(600, 300));

        // Tabbed pane for text output and visualization
        JTabbedPane outputTabs = new JTabbedPane();
        outputTabs.addTab("Text Output", textScrollPane);
        outputTabs.addTab("Visualization", canvasScrollPane);

        // Action listeners
        browseButton.addActionListener(e -> {
            JFileChooser fileChooser = new JFileChooser();
            if (fileChooser.showOpenDialog(panel) == JFileChooser.APPROVE_OPTION) {
                filePathField.setText(fileChooser.getSelectedFile().getAbsolutePath());
            }
        });

        analyzeButton.addActionListener(e -> {
            try {
                String filePath = filePathField.getText().trim();
                if (filePath.isEmpty()) {
                    throw new IllegalArgumentException("Please switch a file first");
                }
                ArrayList<Shape> shapes = parseFile(filePath);
                if (shapes.isEmpty()) {
                    outputArea.append("The shape was not found or the file was invalid.\n");
                    return;
                }
                outputArea.setText("Resolved shapes：\n");
                displayShapes(shapes, outputArea);
                HashMap<String, Integer> counts = countByType(shapes);
                double totalArea = totalArea(shapes);
                outputArea.append("Shape statistics: " + counts + "\n");
                outputArea.append("Total area: " + totalArea + "\n");
                canvas.setShapes(shapes); // Update canvas with parsed shapes
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(panel, "An error occurred while analyzing the shape: " + ex.getMessage());
            }
        });

        visualizeButton.addActionListener(e -> {
            if (lastParsedShapes == null || lastParsedShapes.isEmpty()) {
                JOptionPane.showMessageDialog(panel, "Start by analyzing a shapefile.");
                return;
            }
            outputTabs.setSelectedIndex(1); // Switch to visualization tab
            canvas.repaint(); // Redraw canvas
        });

        panel.add(inputPanel, BorderLayout.NORTH);
        panel.add(outputTabs, BorderLayout.CENTER);
        return panel;
    }

    public JPanel getMainPanel() {
        return createMainPanel();
    }

    // Inner class for shape visualization
    private class ShapeCanvas extends JPanel {
        private ArrayList<Shape> shapes;

        public ShapeCanvas() {
            shapes = new ArrayList<>();
            setBackground(Color.WHITE);
            setPreferredSize(new Dimension(1000, 300)); // Wide canvas for multiple shapes
        }

        public void setShapes(ArrayList<Shape> shapes) {
            this.shapes = shapes != null ? new ArrayList<>(shapes) : new ArrayList<>();
            repaint();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            int xOffset = 20; // Starting x position
            int yOffset = 150; // Center y position
            int spacing = 20; // Space between shapes

            for (Shape shape : shapes) {
                try {
                    if (shape instanceof Circle) {
                        Circle circle = (Circle) shape;
                        double radius = circle.getRadius();
                        int diameter = (int) (radius * 20); // Scale for visibility
                        g2d.setColor(new Color(33, 150, 243)); // Blue
                        g2d.fillOval(xOffset, yOffset - diameter / 2, diameter, diameter);
                        xOffset += diameter + spacing;
                    } else if (shape instanceof Square) {
                        Square square = (Square) shape;
                        double side = square.getSide();
                        int size = (int) (side * 20); // Scale
                        g2d.setColor(new Color(76, 175, 80)); // Green
                        g2d.fillRect(xOffset, yOffset - size / 2, size, size);
                        xOffset += size + spacing;
                    } else if (shape instanceof Rectangle) {
                        Rectangle rectangle = (Rectangle) shape;
                        double width = rectangle.getWidth();
                        double height = rectangle.getHeight();
                        int w = (int) (width * 20); // Scale
                        int h = (int) (height * 20);
                        g2d.setColor(new Color(255, 152, 0)); // Orange
                        g2d.fillRect(xOffset, yOffset - h / 2, w, h);
                        xOffset += w + spacing;
                    } else if (shape instanceof Triangle) {
                        Triangle triangle = (Triangle) shape;
                        // Approximate triangle using average side length
                        double avgSide = (triangle.getSide1() + triangle.getSide2() + triangle.getSide3()) / 3;
                        int size = (int) (avgSide * 20); // Scale
                        int[] xPoints = {xOffset, xOffset + size / 2, xOffset + size};
                        int[] yPoints = {yOffset + size / 2, yOffset - size / 2, yOffset + size / 2};
                        g2d.setColor(new Color(156, 39, 176)); // Purple
                        g2d.fillPolygon(xPoints, yPoints, 3);
                        xOffset += size + spacing;
                    }
                } catch (Exception ex) {
                    // Skip invalid shapes
                }
            }
        }
    }
}